#include "FoGGEDEF.h"
#include "timer.h"

namespace _FOGGE_
{
	namespace _UTIL_
	{
		//--------------------------------------------------------------------------------------
		Timer::Timer()
		{
			m_bUsingQPF         = false;
			m_bTimerStopped     = true;
			m_llQPFTicksPerSec  = 0;

			m_llStopTime        = 0;
			m_llLastElapsedTime = 0;
			m_llBaseTime        = 0;

			// Use QueryPerformanceFrequency() to get frequency of timer.  
			LARGE_INTEGER qwTicksPerSec;
			m_bUsingQPF = (bool) (QueryPerformanceFrequency( &qwTicksPerSec ) != 0);
			m_llQPFTicksPerSec = qwTicksPerSec.QuadPart;
		}


		//--------------------------------------------------------------------------------------
		void Timer::Reset()
		{
			if( !m_bUsingQPF )
				return;

			// Get either the current time or the stop time
			LARGE_INTEGER qwTime;
			if( m_llStopTime != 0 )
				qwTime.QuadPart = m_llStopTime;
			else
				QueryPerformanceCounter( &qwTime );

			m_llBaseTime        = qwTime.QuadPart;
			m_llLastElapsedTime = qwTime.QuadPart;
			m_llStopTime        = 0;
			m_bTimerStopped     = FALSE;
		}


		//--------------------------------------------------------------------------------------
		void Timer::Start()
		{
			if( !m_bUsingQPF )
				return;

			// Get either the current time or the stop time
			LARGE_INTEGER qwTime;
			if( m_llStopTime != 0 )
				qwTime.QuadPart = m_llStopTime;
			else
				QueryPerformanceCounter( &qwTime );

			if( m_bTimerStopped )
				m_llBaseTime += qwTime.QuadPart - m_llStopTime;
			m_llStopTime = 0;
			m_llLastElapsedTime = qwTime.QuadPart;
			m_bTimerStopped = FALSE;
		}


		//--------------------------------------------------------------------------------------
		void Timer::Stop()
		{
			if( !m_bUsingQPF )
				return;

			if( !m_bTimerStopped )
			{
				// Get either the current time or the stop time
				LARGE_INTEGER qwTime;
				if( m_llStopTime != 0 )
					qwTime.QuadPart = m_llStopTime;
				else
					QueryPerformanceCounter( &qwTime );

				m_llStopTime = qwTime.QuadPart;
				m_llLastElapsedTime = qwTime.QuadPart;
				m_bTimerStopped = TRUE;
			}
		}


		//--------------------------------------------------------------------------------------
		void Timer::Advance()
		{
			if( !m_bUsingQPF )
				return;

			m_llStopTime += m_llQPFTicksPerSec/10;
		}


		//--------------------------------------------------------------------------------------
		double Timer::GetAbsoluteTime()
		{
			if( !m_bUsingQPF )
				return -1.0;

			// Get either the current time or the stop time
			LARGE_INTEGER qwTime;
			if( m_llStopTime != 0 )
				qwTime.QuadPart = m_llStopTime;
			else
				QueryPerformanceCounter( &qwTime );

			double fTime = qwTime.QuadPart / (double) m_llQPFTicksPerSec;

			return fTime;
		}


		//--------------------------------------------------------------------------------------
		double Timer::GetTime()
		{
			if( !m_bUsingQPF )
				return -1.0;

			// Get either the current time or the stop time
			LARGE_INTEGER qwTime;
			if( m_llStopTime != 0 )
				qwTime.QuadPart = m_llStopTime;
			else
				QueryPerformanceCounter( &qwTime );

			double fAppTime = (double) ( qwTime.QuadPart - m_llBaseTime ) / (double) m_llQPFTicksPerSec;

			return fAppTime;
		}


		//--------------------------------------------------------------------------------------
		double Timer::GetElapsedTime()
		{
			if( !m_bUsingQPF )
				return -1.0;

			// Get either the current time or the stop time
			LARGE_INTEGER qwTime;
			if( m_llStopTime != 0 )
				qwTime.QuadPart = m_llStopTime;
			else
				QueryPerformanceCounter( &qwTime );

			double fElapsedTime = (double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec;
			m_llLastElapsedTime = qwTime.QuadPart;

			return fElapsedTime;
		}


		//--------------------------------------------------------------------------------------
		bool Timer::IsStopped()
		{
			return m_bTimerStopped;
		}
	}
}